package com.yuyou.tas.lesson.service.impl;

import com.yuyou.tas.lesson.mapper.LessonClassMapper;
import com.yuyou.tas.lesson.mapper.LessonClassPlanChapterMapper;
import com.yuyou.tas.lesson.mapper.LessonClassPlanMapper;
import com.yuyou.tas.lesson.service.*;
import com.yuyou.tas.lesson.vo.req.ReqAddOrUpdateClass;
import com.yuyou.tas.lesson.vo.req.ReqUpdateClassPlanChapter;
import com.yuyou.tas.service.api.admin.entity.AuthUser;
import com.yuyou.tas.service.api.admin.service.AuthUserAPI;
import com.yuyou.tas.service.api.admin.service.CommJobAPI;
import com.yuyou.tas.service.api.feedback.vo.resp.FeedbackClassesVo;
import com.yuyou.tas.service.api.lesson.dto.*;
import com.yuyou.tas.service.api.lesson.entity.*;
import com.yuyou.tas.service.api.lesson.vo.LessonClassVo;
import com.yuyou.tas.util.bean.LoginRedisObj;
import com.yuyou.tas.util.bean.Pagination;
import com.yuyou.tas.util.bean.ResBoolSimpleInfo;
import com.yuyou.tas.util.bean.ResourceObj;
import com.yuyou.tas.util.enums.admin.AuthUserEnums;
import com.yuyou.tas.util.enums.admin.CommJobEnums;
import com.yuyou.tas.util.enums.lesson.LessonClassEnums;
import com.yuyou.tas.util.tool.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class LessonClassServiceImpl implements ILessonClassService {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());  
	
	@Autowired
	private LessonClassMapper lessonClassMapper;

	@Autowired
	private LessonClassPlanMapper lessonClassPlanMapper;

	@Autowired
	private LessonClassPlanChapterMapper  lessonClassPlanChapterMapper;

	@Autowired
	private ILessonClassUserRelService lessonClassUserRelService;

	@Autowired
	private ILessonService lessonService;

	@Autowired
	private ILessonChapterService lessonChapterService;

	@Autowired
	private IBaseSchoolService baseSchoolService;
	
	@Autowired
	private AuthUserAPI authUserAPI;
	
	@Autowired
	private IBaseTermService baseTermService;

	@Autowired
	private ILessonClassChapterService lessonClassChapterService;

	@Autowired
	private CommJobAPI commJobAPI;
	
	@Autowired
	private ILessonClassAopService lessonClassAopService;
	
	@Override
	public int deleteByPrimaryKey(Long id) {
		return lessonClassMapper.deleteByPrimaryKey(id);
	}

	@Override
	public int insert(LessonClass record) {
		if(record.getId()==null){
			record.setId(Sequence.getSequence().nextId());
		}
		record.setCreateTime(DateUtil.now());
		return lessonClassMapper.insert(record);
	}

	@Override
	public LessonClass selectByPrimaryKey(Long id) {
		return lessonClassMapper.selectByPrimaryKey(id);
	}

	@Override
	public int updateByPrimaryKeySelective(LessonClass record) {
		return lessonClassMapper.updateByPrimaryKeySelective(record);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public int addOrUpdateClass(ReqAddOrUpdateClass reqAddOrUpdateClass, LoginRedisObj loginObj) throws Exception {

		LessonClass lessonClass = new LessonClass();
		DefindBeanUtils.copyProperties(reqAddOrUpdateClass, lessonClass);
		lessonClass.setName(reqAddOrUpdateClass.getClassName());

		// 根据时间保存班级状态
		lessonClass.setStatus(lessonClass.getCloseTime().before( DateUtil.now()) ? LessonClassEnums.status.end.getValue() :
				(lessonClass.getOpenTime().after(DateUtil.now()) ? LessonClassEnums.status.init.getValue() : LessonClassEnums.status.opening.getValue()));

		if(null == lessonClass.getId()){
			Long classId=Sequence.getSequence().nextId();
			lessonClass.setId(classId);
			// 引入课件信息
			lessonService.copyClassLesson(true,classId,lessonClass.getLessonId(), loginObj.getUserId(), new ResourceObj(loginObj.getUserId(), lessonClass.getId(), loginObj.getOrganizationId()));
			// 插入班级信息
			lessonClass.setLessonId(lessonClass.getLessonId());

			lessonClass.setAuthOrganizationId(loginObj.getOrganizationId());
			lessonClass.setIsSycn(1);
			lessonClass.setClassStatus(LessonClassEnums.classStatus.init.getValue());//默认未开课
			this.insert(lessonClass);

			
			// 复制讲次信息
			List<LessonChapter> lessonChapterList = lessonChapterService.findLessonChapterByLessId(lessonClass.getLessonId());
			for(LessonChapter lessonChapter : lessonChapterList){
				LessonClassPlanChapter lessonClassPlanChapter = new LessonClassPlanChapter();
				lessonClassPlanChapter.setId(Sequence.getSequence().nextId());
				lessonClassPlanChapter.setLessonClassId(lessonClass.getId());
				lessonClassPlanChapter.setLessonId(lessonChapter.getLessonId());
				lessonClassPlanChapter.setLessonChapterId(lessonChapter.getId());
				lessonClassPlanChapter.setSort(lessonChapter.getSort());
				lessonClassPlanChapter.setCreateTime(DateUtil.now());

				lessonClassPlanChapterMapper.insert(lessonClassPlanChapter);
			}
		}else{
			Lesson lesson=lessonService.selectByPrimaryKey(reqAddOrUpdateClass.getLessonId());
			LessonClass upLessonClass=this.selectByPrimaryKey(reqAddOrUpdateClass.getId());

			//换课程，重新生成班级讲次
			if(!lesson.getId().equals(upLessonClass.getLessonId())){
				lessonClass.setLessonId(lesson.getId());
				//重新同步班级讲次和课件
				lessonClassAopService.sycnClassCopyLesCha(lessonClass,loginObj.getOrganizationId());
			}else{
				lessonClass.setLessonId(null);
			}
			// 更新班级信息
			lessonClassMapper.updateByPrimaryKeySelective(lessonClass);
		}

		// 先删除再添加老师
		lessonClassUserRelService.deleteByLessonClassId(lessonClass.getId());
		List<Long> teacherIdList = Arrays.asList(reqAddOrUpdateClass.getTeacherIds().split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
		for(Long teacherId : teacherIdList){
			LessonClassUserRel lessonClassUserRel = new LessonClassUserRel();
			lessonClassUserRel.setId(Sequence.getSequence().nextId());
			lessonClassUserRel.setAuthUserId(teacherId);
			lessonClassUserRel.setLessonClassId(lessonClass.getId());
			lessonClassUserRel.setType(AuthUserEnums.teacherType.lecturer.getValue());
			lessonClassUserRel.setCreateTime(DateUtil.now());

			lessonClassUserRelService.insert(lessonClassUserRel);
		}
		return 0;
	}

	@Override
	@Transactional(rollbackFor=Exception.class,timeout=60)
	public ResBoolSimpleInfo<String> deleteLessonClass(Long id) {

		// 删除班级
		lessonClassMapper.deleteByPrimaryKey(id);
		//删除班级讲次排班信息课件
		this.delLesCha(id);
		// 班级用户关系删除
		lessonClassUserRelService.deleteByLessonClassId(id);

		//TODO 班级模板,班级模板报告,班级反馈
		
		return new ResBoolSimpleInfo<>(true,null);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public ResBoolSimpleInfo<String> delLesCha(Long classId) {

		// 班级课程讲次删除
		List<LessonClassChapter> lessonClassChapterList = lessonClassChapterService.findByLessonClassId(classId);
		lessonClassChapterService.deleteByLessonClassId(classId);
		// 讲次课件删除
		for(LessonClassChapter lessonClassChapter : lessonClassChapterList){
			if(!StringUtils.isEmpty(lessonClassChapter.getCourseUrl())){
				commJobAPI.addResourceJob(lessonClassChapter.getCourseUrl(), CommJobEnums.type.resource.getValue(), CommJobEnums.tag.resource.getValue());
			}
			if(!StringUtils.isEmpty(lessonClassChapter.getLectureUrl())){
				commJobAPI.addResourceJob(lessonClassChapter.getLectureUrl(), CommJobEnums.type.resource.getValue(), CommJobEnums.tag.resource.getValue());
			}						
		}
		// 排课信息删除
		lessonClassPlanChapterMapper.deleteByLessonClassId(classId);
		return new ResBoolSimpleInfo<>(true,null);
	}

	@Override
	public List<String> findOrgUseByLess(Long lessonId) {
		return lessonClassMapper.findOrgUseByLess(lessonId);
	}

	@Override
	public List<String> findClassNameByLess(Long lessonId) {
		return lessonClassMapper.findClassNameByLess(lessonId);
	}

	@Override
	public List<LessonClass> findLessonClassByClassIds(List<Long> classIds) {
		return lessonClassMapper.findByClassIds(classIds);
	}

	@Override
	public List<LessonClassVo> findLessonClassByOrganId(Long organId) {
		return lessonClassMapper.findLessonClassByOrganId(organId);
	}

	@Override
	public int countLessonClassByLessonIdTrimesterIdStatus(Long lessonId, Long baseTrimesterId, Integer status) {
		return lessonClassMapper.countLessonClassByLessonIdTrimesterIdStatus(lessonId, baseTrimesterId, status);
	}


	@Override
	public int findLessonClassPageCount(Pagination<LessonClassPageDTO> p) {
		return lessonClassMapper.findLessonClassPageCount(p);
	}

	@Override
	public List<LessonClassPageDTO> findLessonClassPageList(Pagination<LessonClassPageDTO> p) {
		List<LessonClassPageDTO> lessonClassList = lessonClassMapper.findLessonClassPageList(p);

		for(LessonClassPageDTO lessonClass : lessonClassList){
			List<AuthUser> teacherOfClass = lessonClassMapper.findTeacherOfClass(lessonClass.getId(), AuthUserEnums.teacherType.lecturer.getValue());
			lessonClass.setTeacherList(teacherOfClass);
		}

		return lessonClassList;
	}

	@Override
	public LessonClassDTO getLessonClass(Long lessonClassId) {

		LessonClassDTO lessonClass = lessonClassMapper.findLessonClassByClassId(lessonClassId);

		// 主讲老师
		List<AuthUser> teacherOfClass = lessonClassMapper.findTeacherOfClass(lessonClassId, AuthUserEnums.teacherType.lecturer.getValue());
		lessonClass.setTeacherList(teacherOfClass);

		// 讲次安排
		List<LessonClassPlanChapterDTO> planChapterList = lessonClassPlanChapterMapper.getPlanChapterByClassId(lessonClassId);
		lessonClass.setLessonClassPlanChapterList(planChapterList);

		return lessonClass;
	}

	@Override
	public List<LessonClassPlanChapterDTO> lessonClassPlanChapterList(Long lessonClassId) {

		// 班级讲次
		List<LessonClassPlanChapterDTO> planChapterList = lessonClassPlanChapterMapper.getPlanChapterByClassId(lessonClassId);
		return planChapterList;
	}



	@Override
	public void updatePlanChapter(List<ReqUpdateClassPlanChapter> updateClassPlanChapterList) {

		for(ReqUpdateClassPlanChapter classPlanChapter :   updateClassPlanChapterList){
			LessonClassPlanChapter lessonClassPlanChapter = new LessonClassPlanChapter();
			lessonClassPlanChapter.setId(classPlanChapter.getId());
			lessonClassPlanChapter.setPlanDate(classPlanChapter.getPlanDate());
			lessonClassPlanChapter.setPlanStartTime(classPlanChapter.getPlanStartTime());
			lessonClassPlanChapter.setPlanEndTime(classPlanChapter.getPlanEndTime());

			lessonClassPlanChapterMapper.updateByPrimaryKeySelective(lessonClassPlanChapter);
		}
	}



	@Override
	public ResBoolSimpleInfo<String> sycnClassByOId(List<LessonClassSyncDTO> list) throws Exception {
		ResBoolSimpleInfo<String> res=new ResBoolSimpleInfo<String>();
		StringBuilder sb=new StringBuilder();
		for(LessonClassSyncDTO dto:list){
			try{
				lessonClassAopService.sycnClassByOId(dto); 
			}catch(Exception e){
				LogUtil.error(logger, "同步班级失败:", e);
				sb.append("同步班级失败:"+e.getMessage()+"|");
			}
		}	
		res.setSuccess(StringUtils.isEmpty(sb.toString()));
		res.setMessage(sb.toString());
		
		return res;
	}

	

	
	
	@Override
	@Deprecated
	public ResBoolSimpleInfo<String> delByOrgan7OId(Long oId,
			Long authOrganizationId) {
//		lessonClassMapper.delByOrgan7OId(oId, authOrganizationId);
		return ResBoolSimpleInfo.getSuccessInfo();
	}
	
	@Override
	@Transactional(rollbackFor=Exception.class,timeout=60)
	public ResBoolSimpleInfo<String> delByOrgan7OIds(List<Long> oIds,
			Long authOrganizationId) {		
		for(Long oId:oIds){
			this.delByOrgan7OId(oId, authOrganizationId);
		}		
		return ResBoolSimpleInfo.getSuccessInfo();
	}

	@Override
	public List<LessonClass> findByLessonId(Long lessonId) {
		return lessonClassMapper.findByLessonId(lessonId);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public ResBoolSimpleInfo<String> upGradeClass(Long id, Long organizationId) throws Exception {
		// 引用课件信息
		LessonClass lc=this.selectByPrimaryKey(id);
		if(lc.getIsSycn().equals(1)){
			return ResBoolSimpleInfo.getSuccessInfo();
		}	
		lessonClassAopService.sycnClassCopyLesCha(lc,organizationId);
		LessonClass lessonClass=new LessonClass();
		lessonClass.setId(lc.getId());
		lessonClass.setIsSycn(1);
		this.updateByPrimaryKeySelective(lessonClass);
		return ResBoolSimpleInfo.getSuccessInfo();
	}


	@Override
	public void updateLessonClassStatus() {
		// 更新未开课班级
		lessonClassMapper.updateInitLessonClassStatus();
		// 更新开课中的班级
		lessonClassMapper.updateOpeningLessonClassStatus();
	}

	@Override
	public LessonClass selectByOrgan7OId(Long oId, Long authOrganizationId) {
		return lessonClassMapper.selectByOrgan7OId(oId, authOrganizationId);
	}

	@Override
	public List<LessonClass> findNeedSycnClassStudent(String startTime) {
		return lessonClassMapper.findNeedSycnClassStudent(startTime);
	}

	@Override
	public ResBoolSimpleInfo<LessonClassPage> findLessonClassByTeacher(Long teacherId, Long schoolId, Long trimesterId, Long sectionId,
													Long levelId, Integer pageSize, Integer pageIndex) {
		LessonClassPage lessonClassPage = new LessonClassPage();
		List<LessonClassDTO> list = new ArrayList<>();
		Integer count = lessonClassMapper.findLessonClassCountByTeacher(teacherId, schoolId ,trimesterId ,sectionId ,levelId);
		if(count != null && count > 0){
			Integer totalPage = (count / pageSize) + (count % pageSize > 0 ? 1 : 0);
			Integer fromRecord = pageSize * pageIndex - pageSize;
			Integer toRecord = pageSize;

			lessonClassPage.setPageIndex(pageIndex);
			lessonClassPage.setPageSize(pageSize);
			lessonClassPage.setTotal(count);
			lessonClassPage.setTotalPage(totalPage);

			list = lessonClassMapper.findLessonClassByTeacher(teacherId, schoolId ,trimesterId ,sectionId ,levelId , fromRecord ,toRecord);
		}
		lessonClassPage.setList(list);
		return new ResBoolSimpleInfo(true , null ,lessonClassPage);
	}

	@Override
	public ResBoolSimpleInfo<List<FeedbackClassesVo>> findFeedbackLessonClassByTeacher(Long teacherId, Long trimesterId) {
		List<FeedbackClassesVo> list = new ArrayList<>();
		List<FeedbackLessonClassDTO> feedbackLessonClassDTOS = lessonClassMapper.findFeedbackLessonClassByTeacher(teacherId , trimesterId);

		Map<Long , List<FeedbackLessonClassDTO>> map = BeanUtils.toGroup(feedbackLessonClassDTOS , "baseSectionId");
		map.forEach(((k, v) -> {
			if(v.size() > 0 && v.get(0) != null){
				FeedbackClassesVo vo = new FeedbackClassesVo();
				vo.setSectionId(k);
				vo.setSectionName(v.get(0).getSection());
				vo.setClasses(v);
				list.add(vo);
			}
		}));

		return new ResBoolSimpleInfo(true , null ,list);
	}

	@Override
	public LessonClassDTO findLessonClassByClassId(Long classId) {
		return lessonClassMapper.findLessonClassByClassId(classId);
	}

	@Override
	public List<LessonClass> findByClassIdsAndClassStatus(List<Long> classIds, Integer classStatus) {
		return lessonClassMapper.findByClassIdsAndClassStatus(classIds, classStatus);
	}


}
